# low-level drivers
.equ CSR_CONCTL, 0xBD2
.equ CSR_CONRECV, 0xBD3
.equ CSR_CONSEND, 0xBD4
.equ CSR_MATP, 0xBC0
.equ SEND_READY, 0x1
.equ RECV_READY, 0x2

.section .text
# system
.globl ll_r_sp
.globl ll_putc # ll_putc (int)
.globl ll_getc 
.globl ll_setmatp # ll_setpgtb (int)
.globl ll_clrmatp
ll_r_sp:
    mv a0, sp
    ret


# for memory address translation and protection
ll_setmatp:
    csrw CSR_MATP, a0
    ret

ll_clrmatp:
    xor t0, t0, t0
    csrw CSR_MATP, t0
    ret

# for console I/O
ll_putc:
    # t寄存器可不压栈
    # addi sp, sp, -4
    # sw t0, 0(sp)
    0:
    csrr t0, CSR_CONCTL
    andi t0, t0, SEND_READY
    bnez t0, 0b
    csrw CSR_CONSEND, a0
    csrr t0, CSR_CONCTL
    ori t0, t0, SEND_READY
    csrw CSR_CONCTL, t0
    # lw t0, 0(sp)
    # addi sp, sp, 4
    ret

ll_getc:
    # addi sp, sp, -8
    # sw t0, 0(sp)
    # sw t1, 4(sp)
    csrr t0, CSR_CONCTL
    andi t0, t0, RECV_READY
    li a0, 0
    beqz t0, 1f
    csrr a0, CSR_CONRECV
    li t0, RECV_READY
    csrr t1, CSR_CONCTL
    not t0, t0
    and t0, t0, t1
    csrw CSR_CONCTL, t0
    1:
    # lw t0, 0(sp)
    # lw t1, 4(sp)
    # addi sp, sp, 8
    ret

# for timer
.equ CSR_MTIME, 0xF15
.equ CSR_MTIMECMP, 0xF16

.globl ll_r_mtime
.globl ll_w_mtimecmp

ll_r_mtime:
    csrr a0, CSR_MTIME
    ret

ll_w_mtimecmp:
    csrw CSR_MTIMECMP, a0
    ret

# for debug device
.equ CSR_TESTNUM, 0xF20
.equ CSR_TESTSTR, 0xF21

.globl ll_testnum
.globl ll_teststr

ll_testnum:
    csrw CSR_TESTNUM, a0
    ret

ll_teststr:
    csrw CSR_TESTSTR, a0
    ret

# for machine control
.equ CSR_MSTATUS, 0x300
.equ CSR_MIE, 0x304
.equ CSR_MTVEC, 0x305
.equ CSR_MSCRATCH, 0x340
.equ CSR_MEPC, 0x341
.equ CSR_MCAUSE, 0x342
.equ CSR_MTVAL, 0x343
.equ CSR_MIP, 0x344
.equ CSR_HALT, 0xC00

.globl ll_w_mtvec
.globl ll_w_mepc
.globl ll_r_mepc
.globl ll_r_mstatus
.globl ll_w_mstatus
.globl ll_r_mcause
.globl ll_r_mscratch
.globl ll_w_mscratch
.globl ll_r_mtval

ll_w_mtvec:
    csrw CSR_MTVEC, a0
    ret

ll_w_mepc:
    csrw CSR_MEPC, a0
    ret

ll_r_mepc:
    csrr  a0, CSR_MEPC
    ret

ll_r_mstatus:
    csrr a0, CSR_MSTATUS
    ret

ll_w_mstatus:
    csrw CSR_MSTATUS, a0
    ret

ll_r_mcause:
    csrr a0, CSR_MCAUSE
    ret
    
ll_r_mscratch:
    csrr a0, CSR_MSCRATCH
    ret

ll_w_mscratch:
    csrw CSR_MSCRATCH, a0
    ret

ll_r_mtval:
    csrr a0, CSR_MTVAL
    ret

.globl ll_halt
# for halt
ll_halt:
    csrw CSR_HALT, 1
    ret

.equ CSR_MFSCTL, 0xBD5
.equ CSR_MFSFUNC, 0xBD6
.equ CSR_MFSARG0, 0xBD7
.equ CSR_MFSARG1, 0xBD8
.equ CSR_MFSARG2, 0xBD9
.equ CSR_MFSARG3, 0xBDA
.equ CSR_MFSRETV, 0xBDB
.equ CSR_MFSCRATCH, 0xBDC
.equ MFSCTL_INVOKE, 0x1

.globl ll_r_mfsctl;
.globl ll_r_mfsret
.globl ll_r_mfscratch
.globl ll_w_mfscratch
.globl ll_r_mfsfunct
.globl ll_mfs_invoke

/* for MagicFS */
ll_r_mfsctl:
    csrr a0, CSR_MFSCTL
    ret

ll_r_mfsret:
    csrr a0, CSR_MFSRETV
    ret

ll_r_mfscratch:
    csrr a0, CSR_MFSCRATCH
    ret

ll_w_mfscratch:
    csrw CSR_MFSCRATCH, a0
    ret

ll_r_mfsfunct:
    csrr a0, CSR_MFSFUNC
    ret

ll_mfs_invoke:
    csrw CSR_MFSARG0,a0
    csrw CSR_MFSARG1,a1
    csrw CSR_MFSARG2,a2
    csrw CSR_MFSARG3,a3
    csrw CSR_MFSFUNC,a4
    csrr t0, CSR_MFSCTL
    or t0, t0, MFSCTL_INVOKE
    csrw CSR_MFSCTL, t0
    ret